﻿using System;
using System.Collections.Generic;
using System.Linq;
using UI;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public static Transform Root => _instance.transform;
    public static Transform FollowTarget => m_followedList[m_followedList.Count - 1];

    private static List<Transform> m_followedList = new List<Transform>();
    public static void AddFollowed(Transform target) => m_followedList.Add(target);

    private static PlayerController _instance;
    
    public float m_moveSpeed;
    public Vector2 m_interactRect;
    public float m_interactHeightOffset;

    private static int s_pause;
    public static void SetPause(bool pause)
    {
        if (pause)
        {
            s_pause++;
        }
        else
        {
            s_pause--;
        }
    }

    private Vector2 m_moveStep;

    private static Collider2D[] s_hits = new Collider2D[10];
    
    private static readonly int Moving = Animator.StringToHash("moving");
    private static readonly int Bubble = Animator.StringToHash("bubble");
    
    private Animator m_animator;
    private Rigidbody2D m_rigidbody;
    private SpriteRenderer m_spriteRenderer;
    private void Awake()
    {
        _instance = this;
        m_followedList.Clear();
        m_followedList.Add(transform);
        
        m_animator = GetComponent<Animator>();
        m_rigidbody = GetComponent<Rigidbody2D>();
        m_spriteRenderer = transform.Find("Model").GetComponent<SpriteRenderer>();
    }
    private void Update()
    {
        if (s_pause > 0)
        {
            m_animator.SetBool(Moving, false);
            return;
        }
        
        var h = Input.GetAxisRaw("Horizontal");
        var v = Input.GetAxisRaw("Vertical");
        if (h != 0 || v != 0)
        {
            m_animator.SetBool(Moving, true);
            m_moveStep = new Vector2(h * m_moveSpeed, v * m_moveSpeed);
            if (h != 0)
            {
                m_spriteRenderer.flipX = h < 0;
            }
        }
        else
        {
            m_moveStep = Vector2.zero;
            m_animator.SetBool(Moving, false);
        }

        if (Input.GetKeyDown(KeyCode.F))
        {
            var filter2D = new ContactFilter2D
            {
                useLayerMask = true,
                layerMask = Layers.Interactable_Mask,
                useDepth = false,
                useTriggers = true,
            };
            var validInteractList = new List<Transform>();
            var center = transform.position + new Vector3(0, m_interactHeightOffset);
            var count = Physics2D.OverlapBox(center, m_interactRect, 0, filter2D, s_hits);
            for (int i = 0; i < count; i++)
            {
                var other = s_hits[i].transform;
                if (other.TryGetComponent(out ItemInfo itemInfo))
                {
                    if (CanGetItem(itemInfo)) validInteractList.Add(other);
                }
                else if (other.TryGetComponent(out ItemTrigger itemTrigger))
                {
                    if (CanUseItem(itemTrigger)) validInteractList.Add(other);
                }
                else if (other.TryGetComponent(out DetailInfo detailInfo))
                {
                    if (CanInteractDetail(detailInfo)) validInteractList.Add(other);
                }
                else if (other.TryGetComponent(out GameTrigger gameTrigger))
                {
                    if (CanInteractGame(gameTrigger)) validInteractList.Add(other);
                }
            }

            if (validInteractList.Count > 0)
            {
                var disSq = 9999f;
                var interact = validInteractList[0];
                for (int i = 1; i < validInteractList.Count; i++)
                {
                    var other = validInteractList[i];
                    var otherDisSq = (other.position - center).sqrMagnitude;
                    if (otherDisSq < disSq)
                    {
                        disSq = otherDisSq;
                        interact = other;
                    }
                }
                if (interact.TryGetComponent(out ItemInfo itemInfo))
                {
                    GetItem(itemInfo);
                }
                else if (interact.TryGetComponent(out ItemTrigger itemTrigger))
                {
                    UseItem(itemTrigger, interact);
                }
                else if (interact.TryGetComponent(out DetailInfo detailInfo))
                {
                    InteractDetail(detailInfo);
                }
                else if (interact.TryGetComponent(out GameTrigger gameTrigger))
                {
                    InteractGame(gameTrigger);
                }
            }
        }
    }
    private void FixedUpdate()
    {
        if (s_pause > 0) return;
        
        m_rigidbody.MovePosition(m_rigidbody.position + m_moveStep * Time.fixedDeltaTime);
    }

    public static bool CanGetItem(ItemInfo info)
    {
        return info.needInfoArr.All(false);
    }
    public static bool GetItem(ItemInfo info)
    {
        if (info.needInfoArr.All(true))
        {
            InventoryManager.AddItem(info.type);
            //触发剧情
            if (!string.IsNullOrEmpty(info.triggerScenario)) UI_ScenarioPanel.StartScenario(info.triggerScenario);
            return true;
        }
        return false;
    }
    public static bool CanUseItem(ItemTrigger trigger)
    {
        return trigger.needInfoArr.All(false);
    }
    public static bool UseItem(ItemTrigger trigger, Transform target)
    {
        if (trigger.needInfoArr.All(true))
        {
            //使用
            trigger.needInfoArr.Use();
            //跟随
            if (trigger is ItemTrigger_Follow && target != null)
            {
                target.parent.GetComponent<InteractRole>().SetFollow(FollowTarget);
                AddFollowed(target);
            }
            //触发剧情
            if (!string.IsNullOrEmpty(trigger.triggerScenario)) UI_ScenarioPanel.StartScenario(trigger.triggerScenario);
            if (trigger.getItemType != EItemType.None) InventoryManager.AddItem(trigger.getItemType);
            return true;
        }
        return false;
    }
    public static bool CanInteractDetail(DetailInfo info)
    {
        return info.needInfoArr.All(false);
    }
    public static bool InteractDetail(DetailInfo info)
    {
        if (info.needInfoArr.All(true))
        {
            if (!string.IsNullOrEmpty(info.triggerScenario)) UI_ScenarioPanel.StartScenario(info.triggerScenario);
            UI_DetailPanel.Trigger(info);
            return true;
        }
        return false;
    }
    public static bool CanInteractGame(GameTrigger trigger)
    {
        return trigger.needInfoArr.All(false);
    }
    public static bool InteractGame(GameTrigger trigger)
    {
        if (trigger.needInfoArr.All(true))
        {
            if (!string.IsNullOrEmpty(trigger.startScenario)) UI_ScenarioPanel.StartScenario(trigger.startScenario);
            UI_LittleGamePanel.StartGame(trigger.gameType);
            return true;
        }
        return false;
    }
    
#if UNITY_EDITOR
    private void OnDrawGizmos()
    {
        Gizmos.DrawWireCube(transform.position + new Vector3(0, m_interactHeightOffset), new Vector3(m_interactRect.x, m_interactRect.y, 1f));
    }
#endif
}